package com.ruoyi.common.utils.uuid;

/**
 * ID生成器工具类
 *
 * @author ruoyi
 */
public class IdUtils {
    private static final long EPOCH = 1609459200000L; // 2021-01-01 00:00:00
    private static final int TIMESTAMP_BITS = 41;
    private static final int MAX_RANDOM_BITS = 14;
    private static final int MAX_RANDOM_VALUE = (1 << MAX_RANDOM_BITS) - 1;

    private long lastTimestamp = -1L;
    private int randomBits = MAX_RANDOM_VALUE;

    public synchronized long generateUniqueId() {
        long currentTimestamp = System.currentTimeMillis() - EPOCH;

        if (currentTimestamp == lastTimestamp) {
            if (randomBits == 0) {
                waitUntilNextTimestamp(currentTimestamp);
            } else {
                randomBits--;
            }
        } else {
            randomBits = MAX_RANDOM_VALUE;
        }

        lastTimestamp = currentTimestamp;

        long id = (currentTimestamp << MAX_RANDOM_BITS) | randomBits;

        return id;
    }

    private void waitUntilNextTimestamp(long currentTimestamp) {
        while (System.currentTimeMillis() - EPOCH <= currentTimestamp) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    /**
     * 获取随机UUID
     *
     * @return 随机UUID
     */
    public static String randomUUID() {
        return UUID.randomUUID().toString();
    }

    /**
     * 简化的UUID，去掉了横线
     *
     * @return 简化的UUID，去掉了横线
     */
    public static String simpleUUID() {
        return UUID.randomUUID().toString(true);
    }

    /**
     * 获取随机UUID，使用性能更好的ThreadLocalRandom生成UUID
     *
     * @return 随机UUID
     */
    public static String fastUUID() {
        return UUID.fastUUID().toString();
    }

    /**
     * 简化的UUID，去掉了横线，使用性能更好的ThreadLocalRandom生成UUID
     *
     * @return 简化的UUID，去掉了横线
     */
    public static String fastSimpleUUID() {
        return UUID.fastUUID().toString(true);
    }
}
